/**
 *  \file I3Key.cpp
 *  \brief This file defines an i3 key.
 */

#include <string>
#include <string.h>
#include <assert.h>

#include "OCD_include.h"

#include "I3Key.h"
#include "I3Id.h"

#include "i3CommonHeaders.h"

/**
  * Constructor.
  */
I3Key::I3Key () {
    
    //blank constructor
}

/**
  * Constructs a new I3Key from string representation of the key.
  * @param keyStr The string representation of the I3 key
  */

I3Key::I3Key(string keyStr) {

    this->keyStr = keyStr;

    char tmpStr[MAX_ID_PRINT_LEN];
    strcpy(tmpStr, keyStr.c_str());
    
    int i;
    char num[3];
  
    if ( strlen(tmpStr) % 2 ) {
        strcat(tmpStr,"0");
    }

    for(i=0;i < KEY_LEN;i++)  {
        key.x[i]=0;
    }
  
    for(i=0;i<strlen(tmpStr);i+=2) {
        
        if ( (i/2) >= KEY_LEN ) {
            break;
        }
    
        num[0] = tmpStr[i];
        num[1] = tmpStr[i+1];
        num[2] = 0;
        key.x[i/2] =  (unsigned char)strtol(num, NULL, 16);
    }
}


/**
  * Gives a string representation (pretty printed) of the I3Key
  * @param tmpStr a character buffer in which the string is stored.
  * Sufficient space should be allocated for tmpStr.
  * @return pointer to tmpStr
  */
char* I3Key::toString(char *tmpStr) {

    char tmpIdBuf[MAX_PRINT_BUF];
    tmpIdBuf[0] = '\0';
    
    for (int index = 0; index < KEY_LEN; index++) {
        char tmpNumBuf[MAX_PRINT_BUF]; //TODO Optimize some space here
        sprintf(tmpNumBuf, "%u", key.x[index]);
        strcat(tmpIdBuf, tmpNumBuf);
    }

    sprintf(tmpStr, "%s (%s)",
            keyStr.c_str(), tmpIdBuf
           );

    return tmpStr;
}

/**
  * Converts the given string to a hex key and stores it in k
  */
void I3Key::convert_str_to_hex(char* source,Key* k) {
    
    int i;
    char num[3];
  
    if ( strlen(source) % 2 ) {
        strcat(source,"0");
    }

    for(i=0;i < KEY_LEN;i++) {
        k->x[i]=0;
    }
  
    for(i=0; i < strlen(source); i += 2) {
        
        if ( (i/2) >= KEY_LEN ) {
            break;
        }
    
        num[0] = source[i];
        num[1] = source[i+1];
        num[2] = 0;
        k->x[i/2] =  (unsigned char)strtol(num, NULL, 16);
    }
}


/* set the key field of a given ID to a random value */
void I3Key::setRandomKey (Key *key) {
  int   i;
  for(i=0; i < KEY_LEN; i++) {
    key->x[i] = (char) (rand() % 255);
  }
}

